package com.ruoyi.system.dubbo;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.enums.UserStatus;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.system.api.RemoteWorkflowUserService;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.WfUserDTO;
import com.ruoyi.system.api.model.WfUserMultiDTO;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.workflow.constant.FlowConstant.*;

/**
 * 工作流选人
 *
 * @author gssong
 */
@RequiredArgsConstructor
@Service
@DubboService
public class RemoteWorkflowUserServiceImpl implements RemoteWorkflowUserService {

    private final SysUserMapper sysUserMapper;

    private final SysRoleMapper sysRoleMapper;

    private final SysDeptMapper sysDeptMapper;

    private final SysUserRoleMapper sysUserRoleMapper;

    /**
     * @description: 通过用户id集合查询
     * @param: ids
     * @return: java.util.List<com.ruoyi.system.api.domain.SysUser>
     * @author: gssong
     * @date: 2022/12/11 19:18
     */
    @Override
    public List<SysUser> selectUserListByIds(List<Long> ids) {
        return sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, ids));
    }

    /**
     * @description: 通过用户id查询
     * @param: id
     * @return: com.ruoyi.system.api.domain.SysUser
     * @author: gssong
     * @date: 2022/12/11 19:18
     */
    @Override
    public SysUser selectUserById(Long id) {
        return sysUserMapper.selectById(id);
    }

    /**
     * @description: 分页查询工作流选人, 角色，部门等
     * @param: wfUserDTO
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @author: gssong
     * @date: 2022/12/11 19:16
     */
    @Override
    public Map<String, Object> getWorkflowUserListByPage(WfUserDTO wfUserDTO) {
        Map<String, Object> map = new HashMap<>(16);
        if (StringUtils.isNotEmpty(wfUserDTO.getParams())) {
            LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
            //检索条件
            queryWrapper.eq(StringUtils.isNotEmpty(wfUserDTO.getDeptId()), SysUser::getDeptId, wfUserDTO.getDeptId());
            queryWrapper.eq(SysUser::getStatus, UserStatus.OK.getCode());
            queryWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getUserName()), SysUser::getUserName, wfUserDTO.getUserName());
            queryWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getPhonenumber()), SysUser::getPhonenumber, wfUserDTO.getPhonenumber());
            Page<SysUser> page = new Page<>(wfUserDTO.getPageNum(), wfUserDTO.getPageSize());
            // 按用户id查询
            String[] split = wfUserDTO.getParams().split(",");
            List<Long> paramList = new ArrayList<>();
            for (String userId : split) {
                paramList.add(Long.valueOf(userId));
            }
            if (WORKFLOW_PERSON.equals(wfUserDTO.getType()) || WORKFLOW_RULE.equals(wfUserDTO.getType())) {
                queryWrapper.in(SysUser::getUserId, paramList);
                Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);
                if (CollectionUtil.isNotEmpty(wfUserDTO.getIds())) {
                    List<SysUser> list = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, wfUserDTO.getIds()));
                    map.put("list", list);
                }
                map.put("page", TableDataInfo.build(recordPage(userPage)));
                return map;
                //按角色id查询用户
            } else if (WORKFLOW_ROLE.equals(wfUserDTO.getType())) {
                List<SysRole> sysRoles = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, paramList));
                if (CollectionUtil.isNotEmpty(sysRoles)) {
                    List<Long> collectRoleId = sysRoles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
                    List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, collectRoleId));
                    queryWrapper.in(SysUser::getUserId, sysUserRoles.stream().map(SysUserRole::getUserId).collect(Collectors.toList()));
                    Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);
                    if (CollectionUtil.isNotEmpty(wfUserDTO.getIds())) {
                        List<SysUser> list = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, wfUserDTO.getIds()));
                        map.put("list", list);
                    }
                    map.put("page", TableDataInfo.build(recordPage(userPage)));
                    return map;
                }
                //按部门id查询用户
            } else if (WORKFLOW_DEPT.equals(wfUserDTO.getType())) {
                queryWrapper.in(SysUser::getDeptId, paramList);
                Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);
                if (CollectionUtil.isNotEmpty(wfUserDTO.getIds())) {
                    List<SysUser> list = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, wfUserDTO.getIds()));
                    map.put("list", list);
                }
                map.put("page", TableDataInfo.build(recordPage(userPage)));
                return map;
            }
        } else {
            if (WORKFLOW_ROLE.equals(wfUserDTO.getType())) {
                LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
                Page<SysRole> rolePage = new Page<>(wfUserDTO.getPageNum(), wfUserDTO.getPageSize());

                //检索条件
                roleWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getRoleName()), SysRole::getRoleName, wfUserDTO.getRoleName());
                roleWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getRoleKey()), SysRole::getRoleKey, wfUserDTO.getRoleKey());
                roleWrapper.eq(SysRole::getStatus, UserStatus.OK.getCode());
                Page<SysRole> roleListPage = sysRoleMapper.selectPage(rolePage, roleWrapper);
                if (CollectionUtil.isNotEmpty(wfUserDTO.getIds())) {
                    List<SysRole> list = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, wfUserDTO.getIds()));
                    map.put("list", list);
                }
                map.put("page", TableDataInfo.build(roleListPage));
            } else if (WORKFLOW_PERSON.equals(wfUserDTO.getType())) {
                LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
                Page<SysUser> page = new Page<>(wfUserDTO.getPageNum(), wfUserDTO.getPageSize());

                //检索条件
                userWrapper.eq(StringUtils.isNotEmpty(wfUserDTO.getDeptId()), SysUser::getDeptId, wfUserDTO.getDeptId());
                userWrapper.eq(SysUser::getStatus, UserStatus.OK.getCode());
                userWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getUserName()), SysUser::getUserName, wfUserDTO.getUserName());
                userWrapper.like(StringUtils.isNotEmpty(wfUserDTO.getPhonenumber()), SysUser::getPhonenumber, wfUserDTO.getPhonenumber());

                Page<SysUser> userPage = sysUserMapper.selectPage(page, userWrapper);
                if (CollectionUtil.isNotEmpty(wfUserDTO.getIds())) {
                    List<SysUser> list = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, wfUserDTO.getIds()));
                    map.put("list", list);
                }
                map.put("page", TableDataInfo.build(recordPage(userPage)));
                return map;
            } else if (WORKFLOW_DEPT.equals(wfUserDTO.getType())) {
                LambdaQueryWrapper<SysDept> roleWrapper = new LambdaQueryWrapper<>();
                roleWrapper.eq(SysDept::getStatus, UserStatus.OK.getCode());
                List<SysDept> deptList = sysDeptMapper.selectList(roleWrapper);
                map.put("list", deptList);
                return map;
            }

        }
        return map;
    }

    /**
     * 翻译部门
     *
     * @param page
     * @return
     */
    private Page<SysUser> recordPage(Page<SysUser> page) {
        List<SysUser> records = page.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return page;
        }
        List<Long> collectDeptId = records.stream().map(SysUser::getDeptId).filter(Objects::nonNull).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(collectDeptId)) {
            return page;
        }
        List<SysDept> sysDepts = sysDeptMapper.selectBatchIds(collectDeptId);
        records.forEach(e -> {
            SysDept sysDept = sysDepts.stream().filter(d -> d.getDeptId().equals(e.getDeptId())).findFirst().orElse(null);
            if (ObjectUtil.isNotNull(sysDept)) {
                e.setDept(sysDept);
            }
        });
        page.setRecords(records);
        return page;
    }

    /**
     * @description: 分页查询工作流选择加签人员
     * @param: wfUserMultiDTO
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @author: gssong
     * @date: 2022/12/11 19:16
     */
    @Override
    public Map<String, Object> getWorkflowAddMultiListByPage(WfUserMultiDTO wfUserMultiDTO) {
        Map<String, Object> map = new HashMap<>(16);
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        //检索条件
        queryWrapper.eq(StringUtils.isNotEmpty(wfUserMultiDTO.getDeptId()), SysUser::getDeptId, wfUserMultiDTO.getDeptId());
        queryWrapper.eq(SysUser::getStatus, UserStatus.OK.getCode());
        if (wfUserMultiDTO.getMulti()) {
            queryWrapper.notIn(CollectionUtil.isNotEmpty(wfUserMultiDTO.getMultiAssigneeList()), SysUser::getUserId, wfUserMultiDTO.getMultiAssigneeList());
        }
        queryWrapper.like(StringUtils.isNotEmpty(wfUserMultiDTO.getUserName()), SysUser::getUserName, wfUserMultiDTO.getUserName());
        queryWrapper.like(StringUtils.isNotEmpty(wfUserMultiDTO.getPhonenumber()), SysUser::getPhonenumber, wfUserMultiDTO.getPhonenumber());
        Page<SysUser> page = new Page<>(wfUserMultiDTO.getPageNum(), wfUserMultiDTO.getPageSize());
        Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);
        if (CollectionUtil.isNotEmpty(wfUserMultiDTO.getIds())) {
            List<SysUser> list = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, wfUserMultiDTO.getIds()));
            map.put("list", list);
        }
        map.put("page", TableDataInfo.build(recordPage(userPage)));
        return map;
    }

    /**
     * @description: 查询审批人
     * @param: params
     * @param: chooseWay
     * @param: nodeName
     * @return: java.util.List<java.lang.Long>
     * @author: gssong
     * @date: 2022/12/11 19:19
     */
    @Override
    public List<Long> getAssigneeIdList(String params, String chooseWay, String nodeName) {
        List<Long> paramList = new ArrayList<>();
        String[] split = params.split(",");
        for (String userId : split) {
            paramList.add(Long.valueOf(userId));
        }
        List<SysUser> list = null;
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        // 按用户id查询
        if (WORKFLOW_PERSON.equals(chooseWay)) {
            queryWrapper.in(SysUser::getUserId, paramList);
            list = sysUserMapper.selectList(queryWrapper);
            //按角色id查询用户
        } else if (WORKFLOW_ROLE.equals(chooseWay)) {
            List<SysRole> sysRoles = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, paramList));
            if (CollectionUtil.isNotEmpty(sysRoles)) {
                List<Long> collectRoleId = sysRoles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
                List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, collectRoleId));
                queryWrapper.in(SysUser::getUserId, sysUserRoles.stream().map(SysUserRole::getUserId).collect(Collectors.toList()));
                list = sysUserMapper.selectList(queryWrapper);
            }
            //按部门id查询用户
        } else if (WORKFLOW_DEPT.equals(chooseWay)) {
            queryWrapper.in(SysUser::getDeptId, paramList);
            list = sysUserMapper.selectList(queryWrapper);
        }
        if (CollectionUtil.isEmpty(list)) {
            throw new ServiceException(nodeName + "任务环节未配置审批人");
        }
        return list.stream().map(SysUser::getUserId).collect(Collectors.toList());
    }
}
